斜率优化真是套路
$f[i]=min(a[i]*b[j]+c[j]+d[i])$
看到这种带当前i和转移j的二次项的,就是斜率优化了
d[i]最后加可以不管,去掉min,然后整理成y=kx+b的形式
$c[j]=-a[i]*b[j]+f[i]$
k为-a[i],b为f[i],(x,y)为(b[j],c[j])
要最大化f[i],就是维护上凸壳
要最小化f[i],就是维护下凸壳
注意起点在哪个位置(一般是(0,0)
还可以考虑比较法
考虑1<=k<j<i
假如j的转移更优要满足的条件
然后推一波式子发现和上面的是一样的
然后是重点(敲黑板
如果b[i]随i有单调性(单调递增最好,如果是单调递减可以提负号好理解
- a[i]有单调性,分成两种单调性,一种随着凸壳往后而往后,一种只会停在第一个点(这种情况几乎不会有吧
复杂度是O(n) - a[i]没有单调性,那么要二分,复杂度O(nlogn)。以下引用:
二分做法:假设你要在上凸包上二分找斜率为k的切线。取中间的mid号点,如果mid+1存在且与mid点的斜率小于k,则l=mid+1;如果mid−1存在且与mid点的斜率大于k,则r=mid−1;如果上面两条都不满足,则mid就是切点。一个很好的斜率优化讲解
bzoj2726
如果b[i]没有单调性(糟糕要动态维护凸包)
那么考虑set/手写平衡树/cdq分治,复杂度O(nlogn)
|
|